package com.jml.jm_usb


import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import androidx.annotation.RequiresApi
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result



/** JmUsbPlugin */
class JmUsbPlugin : FlutterPlugin, MethodCallHandler {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private val TAG = "JmUsbPlugin"
    private lateinit var channel: MethodChannel
    private var applicationContext: Context? = null // 声明一个上下文对象
    private val handler = Handler(Looper.getMainLooper())
    private val usbReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
                    //val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
                    // 在这里处理USB设备连接事件
                    Log.d(TAG, "USB连接: ${intent.dataString}, ${intent.extras}")


                    channel.invokeMethod("onConnect", 1)
                }

                UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                    Log.d(TAG, "USB断开")
                    channel.invokeMethod("onDisconnect", 1)
                }
                UsbManager.ACTION_USB_ACCESSORY_ATTACHED -> {
                    Log.d(TAG, "USB附件连接")
                    channel.invokeMethod("onConnect", 2)
                }

                UsbManager.ACTION_USB_ACCESSORY_DETACHED -> {
                    Log.d(TAG, "USB附件断开")
                    channel.invokeMethod("onDisconnect", 2)
                }
            }
        }
    }

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "jm_usb_method_channel")
        channel.setMethodCallHandler(this)
        applicationContext = flutterPluginBinding.applicationContext
        Usb.init(applicationContext!!) { length ->
            handler.post {
                channel.invokeMethod("onDataLength", length)
            }
        }

        Accessory.init(applicationContext!!) { length ->
            handler.post {
                channel.invokeMethod("onAccessoryDataLength", length)
            }
        }

        val filter = IntentFilter().apply {
            addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
            addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
            addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED)
            addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED)
        }
        applicationContext?.registerReceiver(usbReceiver, filter)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "quickConnectDevice" -> {
                val identifier = call.argument<String>("identifier")
                val configurationIndex = call.argument<Int>("configurationIndex")
                val interfaceIndex = call.argument<Int>("interfaceIndex")
                val endpointInIndex = call.argument<Int>("endpointInIndex")
                val endpointOutIndex = call.argument<Int>("endpointOutIndex")

                val device = Usb.usbDeviceForIdentifier(identifier!!)
                if (device == null) {
                    result.success(false)
                    return
                }

                if (configurationIndex == null || interfaceIndex == null) {
                    Log.w(TAG, "configurationIndex or interfaceIndex is null")
                    result.success(false)
                    return
                }

                Usb.quickConnectDevice(device,
                    configurationIndex,
                    interfaceIndex,
                    endpointInIndex,
                    endpointOutIndex,
                    callback = object : UsbStatusCallback {
                        override fun onComplete(b: Boolean) {
                            Log.d(TAG, "quickConnectDevice onComplete = $b")
                            if (!b) {
                                result.success(false)
                                return
                            }
                            result.success(true)
                        }
                    })
            }

            "quickConnectAccessory" -> {
                Accessory.quickConnectAccessory(

                    callback = object : UsbStatusCallback {
                        override fun onComplete(b: Boolean) {
                            Log.d(TAG, "quickConnectAccessory onComplete = $b")
                            if (!b) {
                                result.success(false)
                                return
                            }
                            result.success(true)
                        }
                    })
            }
            "quickGetFileDescriptor" -> {
                val identifier = call.argument<String>("identifier")
                val configurationIndex = call.argument<Int>("configurationIndex")
                val interfaceIndex = call.argument<Int>("interfaceIndex")
                val endpointInIndex = call.argument<Int>("endpointInIndex")
                val endpointOutIndex = call.argument<Int>("endpointOutIndex")

                val device = Usb.usbDeviceForIdentifier(identifier!!)
                if (device == null) {
                    result.success(-1)
                    return
                }

                if (configurationIndex == null || interfaceIndex == null) {
                    Log.w(TAG, "configurationIndex or interfaceIndex is null")
                    result.success(-1)
                    return
                }

                Usb.quickGetFileDescriptor(device,
                    configurationIndex,
                    interfaceIndex,
                    endpointInIndex,
                    endpointOutIndex,

                    callback = object : UsbStatusCallback {
                        override fun onComplete(b: Boolean) {
                            TODO("Not yet implemented")
                        }

                        override fun onComplete(b: Boolean, message: String,fileDescriptor: Int) {
                            Log.d(TAG, "quickConnectDevice onComplete = $b")
                            if (!b) {
                                result.success(-1)
                                return
                            }
                            result.success(fileDescriptor)
                        }
                    })
            }

            "getDeviceList" -> {
                val deviceList = Usb.getDeviceList()
                val usbDeviceList = deviceList.entries.map {
                    Util.usbDeviceToMap(it.key, it.value)
                }
                result.success(usbDeviceList)
            }

            "getAccessoryList" -> {
                val accessoryList = Accessory.getDeviceList()
                val usbAccessoryList = accessoryList.entries.map {
                    Util.usbAccessoryToMap(it.value)
                }
                result.success(usbAccessoryList)
            }

            "getSerialNumber" -> {
                val serialNumber = Usb.getSerialNumber()
                result.success(serialNumber)
            }

            "getFileDescriptor" -> {
                val fileDescriptor = Usb.getFileDescriptor()
                result.success(fileDescriptor)
            }

            "hasPermission" -> {
                val identifier = call.argument<String>("identifier")
                val device = Usb.usbDeviceForIdentifier(identifier!!)
                if (device == null) {
                    result.success(false)
                    return
                }
                result.success(Usb.hasPermission(device))
            }

            "requestPermission" -> {

                val identifier = call.argument<String>("identifier")
                val device = Usb.usbDeviceForIdentifier(identifier!!)
                if (device == null) {
                    result.success(false)
                    return
                }

                if (Usb.hasPermission(device)) {
                    result.success(true)
                } else {
                    Usb.requestPermission(device, callback = object : UsbStatusCallback {
                        override fun onComplete(b: Boolean) {
                            Log.d(TAG, "requestPermission onComplete = $b")
                            result.success(b)
                        }
                    })
                }

            }

            "openDevice" -> {
                val identifier = call.argument<String>("identifier")
                val device = Usb.usbDeviceForIdentifier(identifier!!)
                if (device == null) {
                    result.success(false)
                    return
                }

                val b = Usb.openDevice(device)

                result.success(b)
            }

            "closeDevice" -> {
                Usb.closeDevice()
                result.success(null)
            }

            "closeAccessory" -> {
                Accessory.closeAccessory()
                result.success(null)
            }

            "controlTransfer" -> {
                val requestType = call.argument<Int>("requestType")!!
                val request = call.argument<Int>("request")!!
                val value = call.argument<Int>("value")!!
                val index = call.argument<Int>("index")!!
                val data = call.argument<ByteArray>("data")!!

                val b = Usb.controlTransfer(requestType, request, value, index, data)
                result.success(b)
            }

            "writeData" -> {
                val data = call.argument<ByteArray>("data")
                val b = Usb.writeData(data!!)
                result.success(b)
            }

            "readData" -> {
                val maxLength = call.argument<Int>("maxLength")!!
                val data = Usb.readData(maxLength)
                result.success(data)
            }

            "accessoryWriteData" -> {
                val data = call.argument<ByteArray>("data")
                val b = Accessory.writeData(data!!)
                result.success(b)
            }

            "accessoryReadData" -> {
                val maxLength = call.argument<Int>("maxLength")!!
                Accessory.readData(maxLength) { data ->
                    result.success(data)
                }

            }


            "startDataListening" -> {
                val type = call.argument<Int>("type") ?: 0 // 默认值为0
                val accumulatedBufferSize = call.argument<Int>("accumulatedBufferSize")!!
                val requestCount = call.argument<Int>("requestCount")!!
                val bufferSize = call.argument<Int>("bufferSize")!!

                when (type) {
                    2 -> {
                        Usb.startDataListeningPipelined2({ data ->
                            handler.post {
                                channel.invokeMethod("onDataReceived", data)
                            }
                        }, accumulatedBufferSize, requestCount, bufferSize)
                    }
                    3 -> {
                        Usb.startDataListeningPipelined3({ data ->
                            handler.post {
                                channel.invokeMethod("onDataReceived", data)
                            }
                        }, accumulatedBufferSize, requestCount, bufferSize)
                    }
                    else -> {
                        Usb.startDataListeningPipelined({ data ->
                            handler.post {
                                channel.invokeMethod("onDataReceived", data)
                            }
                        }, accumulatedBufferSize, requestCount, bufferSize)
                    }
                }



//                Usb.startReading(
//                    { data ->
//                        handler.post {
//                            channel.invokeMethod("onDataReceived", data)
//                        }
//                    },
//                    accumulatedBufferSize, requestCount, bufferSize,
//                )

                result.success(null)
            }

            "stopDataListening" -> {
                Usb.stopDataListening()
                result.success(null)
            }

            else -> {
                result.notImplemented()
            }
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
        applicationContext?.unregisterReceiver(usbReceiver)
        Usb.closeDevice()
    }

    //上传日志到flutter端
    private fun uploadLogToFlutter(log: String) {
        channel.invokeMethod("onLog", log)
    }

    //上传日志到flutter端
    private fun uploadErrorToFlutter(error: String) {
        channel.invokeMethod("onError", error)
    }


}


